package ui;

import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
import java.util.Random;
import java.util.Scanner;

import javax.swing.ImageIcon;
import javax.swing.JDialog;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JMenu;
import javax.swing.JMenuBar;
import javax.swing.JMenuItem;
import javax.swing.border.BevelBorder;

// 主窗口类
public class GameJFrame extends JFrame implements KeyListener,ActionListener{
    static Random r = new Random();
    // 初始化数据
    static int[][] arr = new int[4][4];
    // 成功时的数组
    static int[][] win ={{1,2,3,4},{5,6,7,8},{9,10,11,12},{13,14,15,0}};
    // 定义变量来统计部署
    int step = 0;
    // 创建整个菜单功能的对象
    JMenuBar jMenuBar = new JMenuBar();
    // 创建两个选项功能的对象（功能、关于我们）
    JMenu functionJMenu = new JMenu("功能");
    JMenu aboutJMenu = new JMenu("关于我们");
    // 添加选项下面的条目对象
    JMenu changeImage = new JMenu("切换图片");
    JMenuItem rePlayItem = new JMenuItem("重新游戏");
    JMenuItem reLoginItem = new JMenuItem("重新登录");
    JMenuItem closeGameItem = new JMenuItem("关闭游戏");
    // 切换图片的选项
    JMenuItem goodGirl = new JMenuItem("美女");
    JMenuItem sport = new JMenuItem("运动");
    JMenuItem animal = new JMenuItem("动物");
    // 关于的选项
    JMenuItem accountItem = new JMenuItem("公众号");
    // 记录空白图片在二维数组中的位置
    int x = 0;
    int y = 0;
    // 图片路径
    String path = "./image/animal/animal3/";
    // 初始化窗口
    public GameJFrame(){
        // 初始化屏幕
        initScreen();
        // 初始化项目
        initJMenuBar();
        // 初始化数据
        initData();
        // 初始化图片
        initImage();
        // 设置窗口是否可见
        this.setVisible(true);
    }
    // 初始化选项
    public void initJMenuBar(){
        
        // 给条目添加事件
        rePlayItem.addActionListener(this);
        reLoginItem.addActionListener(this);
        closeGameItem.addActionListener(this);
        accountItem.addActionListener(this);
        goodGirl.addActionListener(this);
        animal.addActionListener(this);
        sport.addActionListener(this);
        // 将选项下面的条目添加到功能选项中
        functionJMenu.add(changeImage);
        functionJMenu.add(rePlayItem);
        functionJMenu.add(reLoginItem);
        functionJMenu.add(closeGameItem);
        // 将选项下面的条目添加到关于选项中
        aboutJMenu.add(accountItem);
        // 将图片类型条目添加到切换图片选项中
        changeImage.add(goodGirl);
        changeImage.add(animal);
        changeImage.add(sport);
        // 整个界面添加选项
        this.setJMenuBar(jMenuBar);
        // 将选项添加到菜单当中
        jMenuBar.add(functionJMenu);
        jMenuBar.add(aboutJMenu);
    }
    // 初始化数据
    public void initData(){
        Random r = new Random();
        int[] my_arr = {0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15};
        // 打乱数组
        for (int i = 0; i < my_arr.length; i++) {
            int random = r.nextInt(arr.length);
            int temp = my_arr[i];
            my_arr[i] = my_arr[random];
            my_arr[random] = temp;
        }
        int index = 0;
        // 给二维数组添加数据
        for (int i = 0; i < arr.length; i++) {
            for (int j = 0; j < arr[i].length; j++) {
                
                arr[i][j] = my_arr[index];
                index++;
            }
        }
    }
    // 初始化图片
    private void initImage(){
        // 清空已有所有图片
        this.getContentPane().removeAll();
        if (victory()){
            // 显示胜利图标
            JLabel winJLabel = new JLabel(new ImageIcon("./image/win.png"));
            winJLabel.setBounds(203,283,197,73);
            this.getContentPane().add(winJLabel);
        }
        JLabel stepCount = new JLabel("步数："+step);
        stepCount.setBounds(50,30,100,20);
        this.getContentPane().add(stepCount);
        for (int j = 0; j < 4; j++) {
            for (int i = 0; i < 4; i++) {
                // 根据二维数组中的数据添加图片
                int num = arr[j][i];
                if(num == 0){
                    x = j;
                    y = i;
                }
                // 创建一个ImageIcon的对象,并创建一个JLabel管理对象（容器）
                JLabel jLabel = new JLabel(new ImageIcon(path+num+".jpg"));
                jLabel.setBounds(105 * i + 83, 105 * j + 108, 105, 105);
                // 设置边框
                jLabel.setBorder(new BevelBorder(BevelBorder.RAISED));
                // 获取当前隐藏容器，并把管理容器加载到界面当中
                this.getContentPane().add(jLabel);
            }
        }
        // 设置背景图片
        JLabel background = new JLabel(new ImageIcon("./image/background.png"));
        // 设置背景图片的位置和大小
        background.setBounds(40,40,508,506);
        // 把背景图片添加到屏幕中
        this.getContentPane().add(background);
        // 刷新一下界面
        this.getContentPane().repaint();
    }
    // 初始化窗口
    public void initScreen(){
        // 设置窗口大小
        this.setSize(603,680);
        // 设置窗口标题
        this.setTitle("拼图小游戏1.0");
        // 设置窗口是否置顶
        this.setAlwaysOnTop(true);
        // 设置界面居中
        this.setLocationRelativeTo(null);
        // 设置关闭模式
        this.setDefaultCloseOperation(3);
        // 取消默认居中放置
        this.setLayout(null);
        // 给整个界面添加键盘事件
        this.addKeyListener(this);
    }
    @Override
    public void keyTyped(KeyEvent e) {
    }
    // 键盘按下不松时触发
    @Override
    public void keyPressed(KeyEvent e) {
        int code = e.getKeyCode();
        // 按a
        if (code == 65){
            // 把界面所有元素删除
            this.getContentPane().removeAll();
            // 加载第一张完整图片
            JLabel all1 = new JLabel(new ImageIcon(path+"all.jpg"));
            all1.setBounds(83,134,420,420);
            // 添加图片
            this.getContentPane().add(all1);
            // 设置背景图片
        JLabel background = new JLabel(new ImageIcon("./image/background.png"));
        // 设置背景图片的位置和大小
        background.setBounds(40,40,508,506);
        // 把背景图片添加到屏幕中
        this.getContentPane().add(background);
        // 刷新界面
        this.getContentPane().repaint();
        }
    }
    // 松开按键时触发
    @Override
    public void keyReleased(KeyEvent e) {
        // 判断游戏是否胜利，胜利则不能触发键盘事件
        if (victory()){
            return;
        }
        // 对上下左右进行判断
        // 左：37，上：38，右：39，下：40
        int code = e.getKeyCode();
        if(code == 39){
            if(y == arr[0].length - 1){
                return;
            }else{
                System.out.println("向左移动");
                arr[x][y] = arr[x][y+1];
                arr[x][y+1] = 0;
                y++;
                // 每移动一次步数加一
                step++;
                //重新加载图片
                initImage();
            }
        }else if(code == 40){
            if (x == arr.length -1){
                return;
            }else{
                System.out.println("向上移动");
                // x,y表示空白图片
                // x+1,y表示空白图片下方的图片  
                // 把空白下方的数字赋给空白图片
                arr[x][y] = arr[x+1][y];
                arr[x+1][y] = 0;
                x++;
                // 每移动一次步数加一
                step++;
                //重新加载图片
                initImage();
            }
            
        }else if(code == 37){
            if(y == 0){
                return;
            }else{
                System.out.println("向右移动");
                arr[x][y] = arr[x][y-1];
                arr[x][y-1] = 0;
                y--;
                // 每移动一次步数加一
                step++;
                //重新加载图片
                initImage();
            }
            
        }else if(code == 38){
            // x为图片列数时表示空白图片在最下面不能再向下移动
            if (x == 0){
                return;
            }else{
                System.out.println("向下移动");
                arr[x][y] = arr[x-1][y];
                arr[x-1][y] = 0;
                x--;
                // 每移动一次步数加一
                step++;
                //重新加载图片
                initImage();
            }
            
        }else if(code == 65){
            // 键盘松开a键时
            initImage();
        }else if(code == 81){
            // 一件通关
            arr = new int[][]{{1,2,3,4},{5,6,7,8},{9,10,11,12},{13,14,15,0}};
            initImage();
        }
    }
    // 判断win数组中的数据与arr数组中的数据是否相同
    public boolean victory(){
        for (int i = 0; i < arr.length; i++) {
            for (int j = 0; j < arr[i].length; j++) {
                // 判断arr数组中是否有一个数据与win数组不同如果有则返回false
                if (arr[i][j] != win[i][j]){
                    return false;
                }
            }
        }
        return true;
    }
    @Override
    public void actionPerformed(ActionEvent e) {
        // 获取当前被点击的条目对象
        Object obj = e.getSource();
        if (obj == rePlayItem){
            // 再次打乱二维数组中的数据
            initData();
            // 计步器清零
            step = 0;
            // 重新加载图片
            initImage();
        }else if(obj == reLoginItem){
            // 关闭当前界面
            this.setVisible(false);
            // 打开登录界面
            new LoginJFrame();
        }else if(obj == closeGameItem){
            // 直接关闭虚拟机
            System.exit(0);
        }else if(obj == accountItem){
            // 创建一个弹框对象
            JDialog jDialog = new JDialog();
            // 创建一个管理的JLabel对象
            JLabel jLabel = new JLabel(new ImageIcon(path+"about .png"));
            // 设置位置和宽高
            jLabel.setBounds(0,0,258,258);
            // 添加到弹框中
            jDialog.getContentPane().add(jLabel);
            // 给弹框设置大小
            jDialog.setSize(344,344);
            // 设置弹框置顶
            jDialog.setAlwaysOnTop(true);
            // 让弹框居中
            jDialog.setLocationRelativeTo(null);
            // 弹框不关闭无法操作下面的数据
            jDialog.setModal(true);
            // 让弹框显示出来
            jDialog.setVisible(true);
        }else if(obj == goodGirl){
            // 选择为美女图片时
            int num = r.nextInt(13)+1;
            // 重新加载图片路径
            path = "./image/girl/girl"+num+"/";
            // 重新加载图片
            initImage();
        }else if(obj == animal){
            // 为动物图片时
            int num = r.nextInt(8)+1;
            // 重新加载图片路径
            path = "./image/animal/animal"+num+"/";
            // 重新加载图片
            initImage();
        }else if(obj == sport){
            // 选择为运动时
            int num = r.nextInt(10)+1;
            System.out.println(num);
            // 重新加载图片路径
            path = "./image/sport/sport"+num+"/";
            // 重新加载图片
            initImage();
        }
    }
}
